import Taro, { Component } from '@tarojs/taro'
import { View, Canvas } from '@tarojs/components'
import Plotter from './Plotter'
import './index.less'
interface EvoWaveLoadingProps {
    width: number,
    height: number,
    percent: number,
    speed: number,
    fontSize: number,
    color: string,
    fontColor: string,
    isShowed: boolean,
    isLandscape: boolean,
    isShowText: boolean,
    onLoadCompleted: () => void
}

interface EvoWaveLoadingState {
    size: number,
    fadeAnim: string
}

export default class EvoWaveLoading extends Component<EvoWaveLoadingProps, EvoWaveLoadingState> {

    static defaultProps: EvoWaveLoadingProps = {
        width: 200,
        height: 200,
        percent: 0,
        speed: 0.5,
        fontSize: 26,
        color: '#00D1E5',
        fontColor: '#FFFFFF',
        isShowed: false,
        isLandscape: false,
        isShowText: true,
        onLoadCompleted: () => {
            throw new Error('onLoadCompleted not implements!')
        }
    }

    plotter: Plotter
    isDrawing: boolean = false
    currPercent: number = 0
    destPercent: number = 0
    currOpacity: number = 0

    constructor(props: EvoWaveLoadingProps) {
        super(props)
        this.state = {
            size: 200,
            fadeAnim: 'opacity: 0;'
        }
    }

    componentWillMount(): void {
        const canvasContext = Taro.createCanvasContext('canvas-wave', this.$scope)
        const size = this.getRealPx(this.props.width)
        this.plotter = new Plotter({
            canvas: canvasContext,
            width: size,
            height: size,
            percent: this.props.percent,
            fontSize: this.props.fontSize,
            color: this.props.color,
            fontColor: this.props.fontColor,
            isLandscape: this.props.isLandscape,
            isShowText: this.props.isShowText
        })
        this.setState({
            size
        }, () => {
            this.updateScene(this.props.isShowed)
        })
    }

    componentWillReceiveProps(nextProps: Readonly<EvoWaveLoadingProps>): void {
        if (this.props.isShowed !== nextProps.isShowed) {
            this.updateScene(nextProps.isShowed)
        }
    }

    /**
     * 更新场景显示/隐藏动画
     */
    updateScene = (isShowed: boolean) => {
        if (isShowed) {
            this.setState({
                fadeAnim: 'animation: fadeIn 2s linear;'
            }, () => {
                this.isDrawing = true
                this.startAnimation()
            })
        } else {
            this.setState({
                fadeAnim: 'animation: fadeOut 2s linear;'
            })
        }
        Plotter.startAnimationFrame(() => {
            let flag: boolean = true
            if (isShowed) {
                if (this.currOpacity >= 1) {
                    this.currOpacity = 1
                    flag = false
                } else {
                    this.currOpacity += 0.02
                    this.plotter.setOpacity(this.currOpacity)
                }
            } else {
                if (this.currOpacity <= 0.001) {
                    this.currOpacity = 0
                    this.isDrawing = false
                    flag = false
                } else {
                    this.currOpacity -= 0.02
                    this.plotter.setOpacity(this.currOpacity)
                }
            }
            return flag
        })
    }

    /**
     * 启动波浪加载动画
     */
    startAnimation = () => {
        Plotter.startAnimationFrame(() => {
            let flagUpd: boolean = true
            if (this.isDrawing) {
                flagUpd = this.updatePercent(this.props.percent)
                this.plotter.updateWave(this.currPercent)
                this.plotter.draw()
            }
            // console.log('wave load', this.isDrawing, flagUpd)
            return (this.isDrawing && flagUpd)
        })
    }

    updatePercent = (percent: number): boolean => {
        let flag: boolean = true
        if (percent > 100) {
            percent = 100
        }
        if (percent > this.destPercent) {
            this.destPercent = percent
        }
        if (this.currPercent >= 100) {
            this.currPercent = 100
            this.handleCompleted()
            flag = false
        } else {
            if (this.currPercent < this.destPercent) {
                this.currPercent += this.props.speed
            }
        }
        return flag
    }

    forceComplete = () => {
        if (this.isDrawing) {
            this.isDrawing = false
        }
    }

    getRealPx = (size: number): number => {
        try {
            const sys = Taro.getSystemInfoSync()
            return size * (sys.screenWidth / 750)
        } catch (error) {
            console.log(error)
            throw error
        }
    }

    render() {
        return (
            <View className='evo-wave-loading' style={this.state.fadeAnim} hidden={!this.props.isShowed}>
                <View className='evo-wave-loading_mask' />
                <Canvas canvasId='canvas-wave' style={'width:' + this.state.size + 'px; height:' + this.state.size + 'px;'} />
            </View>
        )
    }

    handleCompleted = () => {
        this.props.onLoadCompleted()
    }
}
